home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------------------
- *
- * Simple Sample PowerTalk Application Framework
- *
- * ©1991-1993 Apple Computer
- *
- -------------------------------------------------------------------------------------*/
- /*
- * utils.c -- utility routines
- *
- * change history:
- *
- * SJF 08/23/93 1.0f1 update to final headers, fix comments
- * SJF 04/21/93 1.0b2 update to b2
- * SJF 03/01/93 1.0b1 added digital signatures
- * SJF 02/09/93 1.0b1 update to b1
- * SJF 10/13/92 1.0d4 update to a11
- * SJF 09/09/92 1.0d3 update to a9
- * SJF 05/07/92 1.0d2 update to a6
- * SJF 11/06/91 1.0d1 initial coding
- *
- */
-
- #pragma segment othersegment
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __MENUS__
- #include <Menus.h>
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
-
- #ifndef __NOTIFICATION__
- #include <Notification.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifdef THINK_C
- #include <BDC.h> // workaround for think packages.h bug
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __EVENTS__
- #include <Events.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __PALETTES__
- #include <Palettes.h>
- #endif
-
- #ifndef __OCESTANDARDMAIL__
- #include <OCEStandardMail.h>
- #endif
-
- #include "const.h"
- #include "mytypes.h"
- #include "globals.h"
- #include "trapavailable.h"
- #include "main.h"
- #include "mymenus.h"
- #include "strconst.h"
- #include "windowstuff.h"
-
- #include "utils.h"
-
- /* returns true if color quickdraw is available */
-
- Boolean HasColorQD(void)
- {
- SysEnvRec theEnv;
-
- if (SysEnvirons(1,&theEnv) != noErr)
- return false;
-
- return (theEnv.hasColorQD);
- }
-
-
- /* handles an error by displaying an error string via the notification manager or alert */
-
- void DoError(OSErr err)
- {
- Str255 errStr;
- Str255 errNumStr;
- Handle resHandle;
-
- if (err==noErr)
- return;
-
- if (resHandle=GetResource('Estr',err)) { // get our list of error strings
- HLock(resHandle);
- pstrcpy(errStr,*resHandle);
- HUnlock(resHandle);
- ReleaseResource(resHandle);
- }
- else {
- NumToString(err,errNumStr);
- pstrcpy(errStr,"\pAn error has occurred: ");
- pstrcat(errStr,errNumStr);
- }
-
- if (gInBackground)
- Notify(errStr);
- else {
- ParamText(errStr,nil,nil,nil);
- StopAlert(kErrorBoxID,nil);
- }
- }
-
-
- /* post our notification */
-
- void Notify(StringPtr string)
- {
- NMRecPtr nm;
- StringPtr strPtr;
-
- nm = (NMRecPtr)NewPtr(sizeof(NMRec));
- if (MemError()!=noErr)
- return;
- strPtr = (StringPtr)NewPtr(string[0]);
- if (MemError()!=noErr)
- return;
- BlockMove(string,strPtr,string[0]+1);
-
- nm->qType = nmType;
- nm->nmMark = 0;
- nm->nmIcon = nil;
- nm->nmSound = nil;
- nm->nmStr = strPtr;
- nm->nmResp = nil;
- NMInstall(nm);
- }
-
-
- /* pascal string copy function */
-
- void pstrcpy(void *dest,void *src)
- {
- unsigned char srcLen = ((unsigned char *)src)[0];
-
- BlockMove(src,dest,srcLen+1);
- }
-
-
- /* pascal string catenation function */
-
- void pstrcat(void *original,void *catStr)
- {
- short length;
- unsigned char originalLen = ((unsigned char *)original)[0];
- unsigned char catStrLen = ((unsigned char *)catStr)[0];
-
- length = (short) originalLen;
- length += (short) catStrLen;
-
- if (length > 255) {
- DebugStr("\pstring catenation overflow");
- ExitToShell();
- }
-
- BlockMove((char *)catStr+1,(char *)original+originalLen+1,catStrLen);
- ((unsigned char *)original)[0] = (unsigned char) length;
- }
-
-
- /* tries to get a given string out of the resource fork, and if it's not there, copy the */
- /* backup string into storage before returning */
-
- void GetResString(StringPtr storage,short rezID,StringPtr backupString)
- {
- StringHandle rezString;
-
- rezString = GetString(rezID);
- if (rezString) {
- pstrcpy(storage,*rezString);
- ReleaseResource((Handle)rezString);
- }
- else
- pstrcpy(storage,backupString);
- }
-
-
- /* memory manager NewPtr wrapper */
-
- void *NewPtrChk(Size ptrSize)
- {
- Ptr thePtr;
-
- thePtr = NewPtr(ptrSize);
- if (MemError()!=noErr)
- DoError(MemError());
- #if kDEBUG
- {
- long *longPtr = (long *)thePtr;
- *longPtr = kBetterBusErr;
- }
- #endif
- return thePtr;
- }
-
-
- /* memory manager NewHandle wrapper */
-
- void *NewHandleChk(Size hndlSize)
- {
- Handle theHndl;
-
- theHndl = NewHandle(hndlSize);
- if (MemError()!=noErr)
- DoError(MemError());
- #if kDEBUG
- {
- long **longHndl = (long **)theHndl;
- **longHndl = kBetterBusErr;
- }
- #endif
- return theHndl;
- }
-
-
- /* memory manager DisposPtr wrapper */
-
- void DisposPtrChk(void *thePtr)
- {
- #if kDEBUG
- {
- long *longPtr = (long *)thePtr;
- *longPtr = kBetterBusErr;
- }
- #endif
-
- DisposPtr(thePtr);
- if (MemError()!=noErr)
- DoError(MemError());
- }
-
-
- /* memory manager DisposHandle wrapper */
-
- void DisposHandleChk(void *theHndl)
- {
- #if kDEBUG
- {
- long **longHndl = (long **)theHndl;
- **longHndl = kBetterBusErr;
- }
- #endif
-
- DisposHandle(theHndl);
- if (MemError()!=noErr)
- DoError(MemError());
- }
-
-
- /* disables all of the menus in the menubar */
-
- void DisableAllMenus(void)
- {
- MenuHandle theMenu;
- short menuIndex;
-
- for (menuIndex=kAppleMenu+1; menuIndex<kAppleMenu+kNumMenus; menuIndex++) {
- theMenu = GetMHandle(menuIndex);
- DisableItem(theMenu,0);
- }
- }
-
-
- /* enables all of the menus in the menubar */
-
- void EnableAllMenuItems(MenuHandle theMenu)
- {
- short itemIndex,numItems;
-
- numItems = CountMItems(theMenu);
- for (itemIndex=1; itemIndex<=numItems; itemIndex++)
- EnableItem(theMenu,itemIndex);
- EnableItem(theMenu,0);
- }
-
-
- /* sets up our default menu state */
-
- void SetDefaultMenus(void)
- {
- MenuHandle theMenu;
-
- DisableAllMenus();
- theMenu = GetMHandle(kFileMenu);
- EnableAllMenuItems(theMenu);
- DisableItem(theMenu,kCloseItem);
- DisableItem(theMenu,kSaveItem);
- DisableItem(theMenu,kSaveAsItem);
- DisableItem(theMenu,kPageSetupItem);
- DisableItem(theMenu,kPrintItem);
-
- theMenu = GetMHandle(kEditMenu);
- EnableAllMenuItems(theMenu);
- DisableItem(theMenu,kUndoItem);
- DisableItem(theMenu,kCutItem);
- DisableItem(theMenu,kCopyItem);
- DisableItem(theMenu,kPasteItem);
- DisableItem(theMenu,kClearItem);
- DisableItem(theMenu,kSelectAllItem);
-
- theMenu = GetMHandle(kMailMenu);
- EnableAllMenuItems(theMenu);
- DisableItem(theMenu,kAddRemMailItem);
- DisableItem(theMenu,kSendItem);
- DisableItem(theMenu,kReplyItem);
- DisableItem(theMenu,kReplyToAllItem);
- DisableItem(theMenu,kForwardItem);
- DisableItem(theMenu,kTagLetterItem);
-
- theMenu = GetMHandle(kSignMenu);
- DisableItem(theMenu,0);
- }
-
-
- /* sets up the undo command */
-
- void SetUndoCommand(WindowPtr window,WInfoPtr infoPtr,const ShapeList *command)
- {
- gCanUndo = true;
- gHasUndo = false;
- gUndoCommand.window = window;
- gUndoCommand.theShape = *command;
- gUndoCommand.windowRefCount = infoPtr->refCount;
- }
-
-
- /* clears the undo command */
-
- void ClearAppUndo(void)
- {
- gCanUndo = false;
- gHasUndo = false;
- }
-
-
- /* sets the undo string to the appropriate command, if applicable */
-
- Boolean SetupAppUndo(void)
- {
- if (gCanUndo)
- return SetUndoString(gUndoCommand.theShape.shapeType,gHasUndo);
- else
- return SetUndoString(0,false);
- }
-
-
- /* sets the undo string to the appropriate command */
-
- Boolean SetUndoString(short commandID,Boolean redoFlag)
- {
- Str255 undoString;
- MenuHandle theMenu;
- WInfoHndl infoHndl;
-
- if (redoFlag) {
- switch (commandID) {
- case kLineShape:
- GetResString(undoString,kRedoLineID,kRedoLine);
- break;
- case kRectShape:
- GetResString(undoString,kRedoRectID,kRedoRect);
- break;
- case kRoundRectShape:
- GetResString(undoString,kRedoRoundRectID,kRedoRoundRect);
- break;
- case kOvalShape:
- GetResString(undoString,kRedoOvalID,kRedoOval);
- break;
- }
- }
- else {
- switch (commandID) {
- case 0:
- GetResString(undoString,kUndoStringID,kUndoString);
- break;
- case kLineShape:
- GetResString(undoString,kUndoLineID,kUndoLine);
- break;
- case kRectShape:
- GetResString(undoString,kUndoRectID,kUndoRect);
- break;
- case kRoundRectShape:
- GetResString(undoString,kUndoRoundRectID,kUndoRoundRect);
- break;
- case kOvalShape:
- GetResString(undoString,kUndoOvalID,kUndoOval);
- break;
- }
- }
-
- theMenu = GetMHandle(kEditMenu);
- SetItem(theMenu,kUndoItem,undoString);
-
- if (MyFrontWindow())
- infoHndl = GetWindowInfo(MyFrontWindow());
-
- if (gCanUndo && MyFrontWindow() && ((**infoHndl).refCount==gUndoCommand.windowRefCount) &&
- commandID!=0) {
- EnableItem(theMenu,kUndoItem);
- return true;
- }
- else {
- DisableItem(theMenu,kUndoItem);
- return false;
- }
- }
-
-
- /* read our prefs global from disk */
-
- void ReadPrefs(void)
- {
- FSSpec prefsSpec;
- short refNum;
- long count;
- OSErr err;
-
- refNum = 0;
-
- GetPrefsFolder(&prefsSpec);
- err = FSpOpenDF(&prefsSpec,fsRdPerm,&refNum);
- if (err!=noErr) {
- err = FSpCreate(&prefsSpec,kAppCreator,kPrefsType,smRoman);
- if (err==noErr)
- err = FSpOpenDF(&prefsSpec,fsRdPerm,&refNum);
- }
-
- if (err==noErr) {
- count = sizeof(MyPreferences);
- err = FSRead(refNum,&count,&gPreferences);
- if (err==noErr && gPreferences.version!=kPrefsVersion)
- err = -1;
- }
-
- if (err!=noErr) {
-
- // set default preferences
-
- gPreferences.version = kPrefsVersion;
- gPreferences.sendOptions.signWhenSent = false;
- gPreferences.sendOptions.priority = kIPMNormalPriority;
- gPreferences.closeOptions.moveToTrash = false;
- gPreferences.closeOptions.addTag = false;
- gPreferences.closeOptions.tag.dataLength = 0;
- gPreferences.sendFormat.whichFormats = kSMPNativeMask | kSMPStandardInterchangeMask;
- gPreferences.sendFormat.whichNativeFormat = 0;
- gPreferences.closeOnSend = false;
- gPreferences.closeOptionsDialog = true;
- gPreferences.expandOnCreate = true;
- gPreferences.expandOnOpen = false;
- }
-
- if (refNum!=0)
- FSClose(refNum);
- }
-
-
- /* write our prefs global to disk */
-
- void WritePrefs(void)
- {
- FSSpec prefsSpec;
- short refNum;
- long count;
- OSErr err;
-
- GetPrefsFolder(&prefsSpec);
-
- refNum = 0;
-
- err = FSpOpenDF(&prefsSpec,fsRdWrPerm,&refNum);
- if (err!=noErr) {
- err = FSpCreate(&prefsSpec,kAppCreator,kPrefsType,smRoman);
- if (err==noErr)
- err = FSpOpenDF(&prefsSpec,fsRdWrPerm,&refNum);
- }
-
- if (err==noErr) {
- count = sizeof(MyPreferences);
- err = FSWrite(refNum,&count,&gPreferences);
- }
-
- if (refNum!=0)
- FSClose(refNum);
- }
-
-
- /* get the folder the prefs file is in */
-
- void GetPrefsFolder(FSSpec *fSpec)
- {
- long gestResponse;
- SysEnvRec sysEnv;
- WDPBRec pBlock;
- Str255 fName;
- OSErr err;
-
- err = -1;
-
- // the new system 7 way
-
- if (TrapAvailable(_Gestalt) &&
- (Gestalt(gestaltFindFolderAttr,&gestResponse)==noErr) &&
- (gestResponse && (1<<gestaltFindFolderPresent))) {
- err = FindFolder(kOnSystemDisk,kPreferencesFolderType,false,&fSpec->vRefNum,
- &fSpec->parID);
- }
-
- // the old system 6 way
-
- if (err!=noErr) {
- SysEnvirons(1,&sysEnv);
- fName[0] = 0;
- pBlock.ioVRefNum = sysEnv.sysVRefNum;
- pBlock.ioNamePtr = fName;
- pBlock.ioWDIndex = 0;
- pBlock.ioWDProcID = 0;
- pBlock.ioWDVRefNum = 0;
- err = PBGetWDInfo(&pBlock,false);
- if (err!=noErr) {
- fSpec->vRefNum = -1;
- fSpec->parID = fsRtDirID;
- }
- }
-
- GetResString(fSpec->name,kPrefsFileID,kPrefsFile);
- }
-
-
- #define kButtonFrameInset -4
- #define kButtonFrameSize 3
- #define kCntrActivate 0
- #define kColorPortMask 0xc000
- #define kActivateControl 0
-
- /* draw outline for default button */
-
- void MyDrawDefaultButtonOutline(DialogPtr theDialog,short theItem)
- {
- short itemType;
- Rect itemRect;
- ControlHandle itemHandle;
- PenState curPen;
- short buttonOval;
- RGBColor fgSaveColor,bgColor,newFGColor;
- Boolean newGray;
- WindowPtr oldPort;
- Boolean isColor;
- GDHandle targetDevice;
-
- // get the default button and draw a bold border around it
-
- GetDItem(theDialog,theItem,&itemType,(Handle *)&itemHandle,&itemRect);
- GetPort(&oldPort);
- SetPort((**itemHandle).contrlOwner);
- GetPenState(&curPen);
-
- PenNormal();
- InsetRect(&itemRect,kButtonFrameInset,kButtonFrameInset);
- FrameRoundRect(&itemRect,16,16);
-
- buttonOval = ((itemRect.bottom-itemRect.top)/2) + 2;
- if (((CGrafPtr)((**itemHandle).contrlOwner))->portVersion & kColorPortMask)
- isColor = true;
- else
- isColor = false;
-
- if ((**itemHandle).contrlHilite != kActivateControl) { // control is dimmed, so draw gray
- newGray = false;
- if (isColor) {
- GetBackColor(&bgColor);
- GetForeColor(&fgSaveColor);
- newFGColor = fgSaveColor;
- targetDevice = MyGetDeviceFromRect(&(**itemHandle).contrlRect);
- newGray = GetGray(targetDevice,&bgColor,&newFGColor);
- }
- if (newGray)
- RGBForeColor(&newFGColor);
- else
- #ifdef dangerousPattern
- PenPat(qd.gray);
- #else
- PenPat(&qd.gray);
- #endif
- PenSize(kButtonFrameSize,kButtonFrameSize);
- FrameRoundRect(&itemRect,buttonOval,buttonOval);
- if (isColor)
- RGBForeColor(&fgSaveColor);
- }
- else {
- #ifdef dangerousPattern
- PenPat(qd.black);
- #else
- PenPat(&qd.black);
- #endif
- PenSize(kButtonFrameSize,kButtonFrameSize);
- FrameRoundRect(&itemRect,buttonOval,buttonOval);
- }
-
- SetPenState(&curPen);
- SetPort(oldPort);
- }
-
-
- GDHandle MyGetDeviceFromRect(Rect *localRect)
- {
- GDHandle device;
- Point wCenter;
-
- wCenter.v = localRect->bottom-localRect->top;
- wCenter.h = localRect->right-localRect->left;
- LocalToGlobal(&wCenter);
-
- device = GetDeviceList();
- while (device) {
- if (PtInRect(wCenter,&(**device).gdRect))
- return device;
- device = GetNextDevice(device);
- }
-
- return GetMainDevice();
- }
-